package com.ysd.twocrm.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ysd.twocrm.config.AlipayConfig;
import com.ysd.twocrm.entity.Logs;
import com.ysd.twocrm.entity.Orders;
import com.ysd.twocrm.entity.Users;
import com.ysd.twocrm.mapper.LogsMapper;
import com.ysd.twocrm.mapper.OrdersMapper;
import com.ysd.twocrm.utils.LayuiUtils;
import com.ysd.twocrm.utils.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/orders")
//订单表
public class OrdersController {
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private LogsMapper logsMapper;

    Logger log= LoggerFactory.getLogger(OrdersController.class);
    /*
     * @Description 根据用户id来进行判断，如果当前用户在订单表里存在了，则返回给前台，具体显示在前台看效果
     * @param userId 用户id
     * @return java.lang.String
     * @author liusupeng
     * @date 2020/4/29 11:33
     */
    @GetMapping
    public String isOrdersByUserId(Integer userId){

        QueryWrapper<Orders> queryWrapper=new QueryWrapper<Orders>();
        queryWrapper.eq("userId",userId);
        Orders orders = ordersMapper.selectOne(queryWrapper);
        if(orders!=null){
            return "success";
        }
        return "false";
    }
    /*
     * @Description 返回layui格式的，通过当前用户来查询当前的订单信息
     * @param userId
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/4/29 11:34
     */
    @GetMapping("/1")
    public Object getLayuiOrders(Integer userId){

        QueryWrapper<Orders> queryWrapper=new QueryWrapper<Orders>();
        queryWrapper.eq("userId",userId);
        List<Orders> orders = ordersMapper.selectList(queryWrapper);
        LayuiUtils<Orders> ordersLayuiUtils=new LayuiUtils<Orders>();
        ordersLayuiUtils.setCount((long) 1);
        ordersLayuiUtils.setData(orders);

        return ordersLayuiUtils;
    }
    /*
     * @Description 待付款页面，因为以防账户无意间关闭支付页面，所以为他开启一个待付款功能
     * 当点击待付款就是将自己的信息存起来然后依然是转发给支付页面，当然页面跳转还是在前台
     * @param o
     * @param session
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/4/29 11:32
     */
    @GetMapping("/2")
   public Object getRepetionOrders(Orders o,HttpSession session){

        session.setAttribute("orderId",o.getOrderId());
        session.setAttribute("orderMoney",o.getOrderMoney());
        session.setAttribute("orderName",o.getOrderName());
        return "success";
   }
    /*
     * @Description 根据传来的用户id来判断当前用户是否已付款，如果付款则返回success
     * @param userId
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/5/13 9:45
     */
@GetMapping("/3")
   public Object getAllOrdersById(Integer userId){

       Orders orders = ordersMapper.selectOrdersByUserId(userId);
       if(orders!=null){
           return "success";
       }
       return false;
   }

    /*
     * @Description 添加订单信息，并用session存起来用于支付
     * @param o
     * @param session
     * @return java.lang.String
     * @author liusupeng
     * @date 2020/4/29 11:31
     */
    @PostMapping
    public String insertOrders(Orders o,HttpSession session){

        o.setOrderId((String) UUID.createCheckUUID());
        o.setOrderBegin(new Date());
        int insert = ordersMapper.insert(o);
        if(insert>0){
            session.setAttribute("orderId",o.getOrderId());
            session.setAttribute("orderMoney",o.getOrderMoney());
            session.setAttribute("orderName",o.getOrderName());
            return "success";
        }
       return "false";
    }

    /*
     * @Description 阿里云的支付页面，在这里面我们传入公钥密钥以及等信息，并且存下同步、异步的页面，同步异步页面在下方
     * 当然这里面的一些订单编号啊还有金额啊还有什么都需要再session中读取
     * @param session
     * @param request
     * @param response
     * @return void
     * @author liusupeng
     * @date 2020/4/29 11:35
     */

@GetMapping("/alipay")
    public void alipay(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException {

        //设置响应编码格式
        response.setContentType("text/html;charset=utf-8");
        //获得初始化的AllipayClient(需要存储支付宝网关、APPID、商户私钥、字符编码格式、支付宝公钥、签名方式)
        //这里的存储的都在alipayconfig类里面
        AlipayClient alipayClient=new DefaultAlipayClient(AlipayConfig.gatewayUrl,
                AlipayConfig.app_id,AlipayConfig.merchant_private_key,
                "json",AlipayConfig.charset,
                AlipayConfig.alipay_public_key,AlipayConfig.sign_type);
        //设置请求参数
        AlipayTradePagePayRequest alipayTradePagePayRequest=new AlipayTradePagePayRequest();
        alipayTradePagePayRequest.setReturnUrl(AlipayConfig.return_url);//同步页面
        alipayTradePagePayRequest.setNotifyUrl(AlipayConfig.notify_url);//异步页面
        String out_trade_no = (String)session.getAttribute("orderId");//订单编号*
        String total_amount=String.valueOf((Double)session.getAttribute("orderMoney"));//订单金额*
        String subject=(String)session.getAttribute("orderName");//订单名称*
       log.info("******************");
        log.info("session:编号"+out_trade_no);
    log.info("session:金额"+total_amount);
    log.info("session:订单名称"+subject);
    log.info("******************");
/**
 *  该笔订单允许的最晚付款时间，逾期将关闭交易。
 *         取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天
 *         （1c-当天的情况下，无论交易何时创建，都在0点关闭）。
 *          该参数数值不接受小数点， 如 1.5h，可转换为 90m。
 */
        String timeout_express="1c";//代表1天，当天不论何时创建都会在0点结束
        alipayTradePagePayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"total_amount\":\"" + total_amount
                + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + 2 + "\"," + "\"timeout_express\":\""
                + timeout_express + "\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        // 设置返回页面
        String result = alipayClient.pageExecute(alipayTradePagePayRequest).getBody();
        //把页面返回
        response.getWriter().write(result);
    }

    @GetMapping("/alipayReturnNotice")
    public Object alipayReturnNotice(Model model,HttpSession session,HttpServletRequest request,HttpServletResponse response) throws IOException, AlipayApiException {
    log.info("支付成功，进入同步通知接口");
    //获取支付宝GET过来反馈信息
        Map<String,String> params=new HashMap<String,String>();
        Map<String,String[]> requestParams=request.getParameterMap();
        for(Iterator<String> iter=requestParams.keySet().iterator();iter.hasNext();){
            String name=iter.next();
            String[] values=(String[])requestParams.get(name);
            String valueStr="";
            for(int i=0;i<values.length;i++){
                valueStr=(i==values.length-1)?valueStr+values[i]:valueStr+values[i]+",";
            }
            //乱码解决
          //  valueStr=new String(valueStr.getBytes("ISO-8859-1"),"utf-8");
            params.put(name,valueStr);
        }
        //调用sdk来验证签名
        boolean signVerified= AlipaySignature.rsaCheckV1(params,AlipayConfig.alipay_public_key,AlipayConfig.charset,AlipayConfig.sign_type);;
        //判断验证签名
        if(signVerified){
            //这里面读取的是在alipay方法里也就是上面的
            // 商户订单号(在订单表里的主键)
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            // 支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            // 付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");
            //修改订单状态
            ordersMapper.updateOrdersStatusByOId(out_trade_no,trade_no,0);//根据id来修改状态为付款成功
            //根据订单编号来查询用户
            Users users = ordersMapper.selectUsersByOrdersId(out_trade_no);
            //准备开始向日志表插入数据
            String caozuo="通过支付宝支付的方式交了学费";
            String logsParams="支付金额:"+total_amount+"支付宝交易号:"+trade_no+"订单号"+out_trade_no+"";
            Logs logs=new Logs(0,users.getUserId(),users.getUserName(),caozuo,"post",logsParams,new Date());
            logsMapper.insert(logs);
            log.info("********************** 支付成功(支付宝同步通知) **********************");
            log.info("* 订单号: {}", out_trade_no);
            log.info("* 支付宝交易号: {}", trade_no);
            log.info("* 实付金额: {}", total_amount);
            log.info("***************************************************************");
        }else{
            log.info("支付验签失败");
            return "false";
        }
        response.sendRedirect("http://127.0.0.1:8848/twocrm/src/views/index.html");
    return "success";
    }

    @GetMapping("/alipayNotifyNotice")
    public String alipayNotifyNotice(Model model,HttpSession session,HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException, AlipayApiException {
        log.info("支付成功，进入异步通知接口");
        //获取支付宝GET过来反馈信息
        Map<String,String> params=new HashMap<String,String>();
        Map<String,String[]> requestParams=request.getParameterMap();
        for(Iterator<String> iter=requestParams.keySet().iterator();iter.hasNext();){
            String name=iter.next();
            String[] values=(String[])requestParams.get(name);
            String valueStr="";
            for(int i=0;i<values.length;i++){
                valueStr=(i==values.length-1)?valueStr+values[i]:valueStr+values[i]+",";
            }
            //乱码解决
            valueStr=new String(valueStr.getBytes("ISO-8859-1"),"UTF-8");
            params.put(name,valueStr);
        }
        //调用sdk来验证签名
        boolean signVerified= AlipaySignature.rsaCheckV1(params,AlipayConfig.alipay_public_key,AlipayConfig.charset,AlipayConfig.sign_type);;
        //判断验证签名
        if(signVerified){
            //这里面读取的是在alipay方法里也就是上面的
            // 商户订单号(在订单表里的主键)
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            // 支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            // 付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");
            //修改订单状态
            ordersMapper.updateOrdersStatusByOId(out_trade_no,trade_no,0);//根据id来修改状态为付款成功
            //根据订单编号来查询用户
            Users users = ordersMapper.selectUsersByOrdersId(out_trade_no);
            //准备开始向日志表插入数据
            String caozuo="通过支付宝支付的方式交了学费";
            String logsParams="支付金额:"+total_amount+"支付宝交易号:"+trade_no+"订单号"+out_trade_no+"";
            Logs logs=new Logs(0,users.getUserId(),users.getUserName(),caozuo,"post",logsParams,new Date());
            logsMapper.insert(logs);
            log.info("********************** 支付成功(支付宝同步通知) **********************");
            log.info("* 订单号: {}", out_trade_no);
            log.info("* 支付宝交易号: {}", trade_no);
            log.info("* 实付金额: {}", total_amount);
            log.info("***************************************************************");
        }else{
            log.info("支付验签失败");
            return "false";
        }
        return "success";
    }

}
